package org.devgframwork.datasync.core.support.executors;

import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.devgframwork.datasync.core.entity.ScheduleConfig;
import org.devgframwork.datasync.core.entity.TargetConfig;
import org.devgframwork.datasync.core.model.ExecutorModel;
import org.devgframwork.datasync.core.model.ResultModel;
import org.devgframwork.datasync.core.support.DataSourceMemory;
import org.devgframwork.datasync.core.support.service.ScheduleConfigService;
import org.devgframwork.datasync.core.utils.CommonUtil;
import org.slf4j.Logger;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;
import java.util.Map;

public interface AbstractExecutor<T> {


    ResultModel invoke(ExecutorModel<T> executorModel);

    default String getMaxTrackColumnValue(JdbcTemplate jdbcTemplate, String sqlText, ScheduleConfig scheduleConfig) {
        Integer isTrack = scheduleConfig.getIsTrack();
        String trackColumnName = scheduleConfig.getTrackColumnName();
        String maxTrackColumnValue = null;
        if (null == isTrack || !isTrack.equals(1) || CommonUtil.isEmpty(trackColumnName)) {
            return maxTrackColumnValue;
        }
        String sqlMax = "select " + trackColumnName + " from (" + sqlText + ") _sqlMax";
        List<Map<String, Object>> list = jdbcTemplate.queryForList(sqlMax);
        if (!CommonUtil.isEmpty(list)) {
            Map<String, Object> map = list.get(0);
            maxTrackColumnValue = CommonUtil.mapToString(map, trackColumnName);
        }
        return maxTrackColumnValue;
    }

    default void updateSyncNumber(ScheduleConfigService scheduleConfigService, Long scheduleConfigId, int count) {
        ScheduleConfig countScheduleConfig = new ScheduleConfig();
        countScheduleConfig.setTotalNum(count);
        UpdateWrapper<ScheduleConfig> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("SCHEDULE_CONFIG_ID", scheduleConfigId);
        scheduleConfigService.update(countScheduleConfig, updateWrapper);
    }

    default void realseRunning(ScheduleConfigService scheduleConfigService, Long scheduleConfigId, Long startTime, String trackColumnValue) {
        long endTime = System.currentTimeMillis();
        ScheduleConfig configPo = new ScheduleConfig();
        configPo.setScheduleConfigId(scheduleConfigId);
        if (!CommonUtil.isEmpty(trackColumnValue)) {
            configPo.setTrackColumnValue(trackColumnValue);
        }
        configPo.setSyncTime(endTime - startTime);
        configPo.setIsRunning(0);
        scheduleConfigService.updateById(configPo);
    }


    default ResultModel preCheck(ScheduleConfig scheduleConfig, Logger log) {
        if (null == scheduleConfig) {
            return ResultModel.newFail("配置为空");
        }
        String sourceKey = scheduleConfig.getSourceKey();
        if (CommonUtil.isNullOrEmpty(sourceKey)) {
            log.error("sync taskName:{} sourceKey:{} 不存在!", scheduleConfig.getTaskName(), sourceKey);
            return ResultModel.newFail("配置错误");
        }
        String sourceContent = scheduleConfig.getSourceContent();
        if (CommonUtil.isNullOrEmpty(sourceContent)) {
            log.error("sync taskName:{} sourceContent:{} 不存在!", scheduleConfig.getTaskName(), sourceContent);
            return ResultModel.newFail("配置错误");
        }
        List<TargetConfig> targetConfigList = scheduleConfig.getTargetConfigList();
        if (CommonUtil.isEmpty(targetConfigList)) {
            log.error("sync taskName:{} targetInfo 不能为空!", scheduleConfig.getTaskName());
            return ResultModel.newFail("配置错误");
        }
        ScheduleConfigService scheduleConfigService = DataSourceMemory.applicationContext.getBean(ScheduleConfigService.class);
        ScheduleConfig configPo = new ScheduleConfig();
        configPo.setSyncNum(0);
        configPo.setIsRunning(1);
        configPo.setSyncTime(0L);
        UpdateWrapper<ScheduleConfig> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("SCHEDULE_CONFIG_ID", scheduleConfig.getScheduleConfigId());
        updateWrapper.eq("IS_RUNNING", 0);
        boolean resonse = scheduleConfigService.update(configPo, updateWrapper);
        if (!resonse) {
            log.error("sync taskName:{} is Running!", scheduleConfig.getTaskName());
            return ResultModel.newFail("taksName正在执行中");
        }
        return ResultModel.newSuccess();
    }
}
